package com.inspur.edp.web.relycheck.dependencygenerator;

import com.inspur.edp.lcm.metadata.api.entity.GspMetadata;
import com.inspur.edp.lcm.metadata.spi.entity.MetadataElementDependencyDetail;
import com.inspur.edp.web.common.utility.ListUtility;
import com.inspur.edp.web.formmetadata.metadata.formdom.FormDOM;
import com.inspur.edp.web.relycheck.constant.RelyCheckType;
import com.inspur.edp.web.relycheck.dependencygenerator.entity.SourceElementEntity;
import com.inspur.edp.web.relycheck.elements.CustomEntity;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * 表单元数据 schema  entity  依赖项构造
 * 此处每次返回新实例的原因是该方法执行次数极少，定义bean的scope 为  prototype
 * 所以为了更加方便垃圾回收 设计为每次 new 新实例
 *
 * @author noah
 */
public class SchemaEntityDependencyGenerator {

    private final RelyCheckType entityRelyCheckType = RelyCheckType.SchemaEntity;

    /**
     * 字段一致性检查
     * 字段生成项
     */
    @Resource
    private SchemaFieldDependencyGenerator schemaFieldDependencyGenerator;

    /**
     * 依据 schema  entity 列表构造依赖
     *
     * @param schemaCustomEntityList schema entity 列表
     * @return
     */
    public List<MetadataElementDependencyDetail> generateDependencyDetailWithSchemaEntityList(List<CustomEntity> schemaCustomEntityList, FormDOM formDOM, GspMetadata gspMetadata) {
        if (ListUtility.isEmpty(schemaCustomEntityList)) {
            return new ArrayList<>(0);
        }
        List<MetadataElementDependencyDetail> dependencyDetailList = new ArrayList<>();
        schemaCustomEntityList.forEach(entityItem -> {
            // 依据字段列表 构造对应的依赖信息
            List<MetadataElementDependencyDetail> entityDependencyDetailList = this.generateDependencyDetailWithSchemaEntity(entityItem, formDOM, gspMetadata);
            ListUtility.add(dependencyDetailList, entityDependencyDetailList);
        });
        return dependencyDetailList;
    }


    /**
     * 依据 schemaEntity 构造对应的依赖信息
     *
     * @param schemaCustomEntity schema entity 信息
     */
    private List<MetadataElementDependencyDetail> generateDependencyDetailWithSchemaEntity(CustomEntity schemaCustomEntity, FormDOM formDOM, GspMetadata gspMetadata) {
        if (schemaCustomEntity == null) {
            return new ArrayList<>(0);
        }
        List<MetadataElementDependencyDetail> entityDependencyDetailList = new ArrayList<>();

        MetadataElementDependencyDetail metadataElementDependencyDetail = new MetadataElementDependencyDetail();

        // 构造传递的源参数
        SourceElementEntity sourceElementEntity = SourceElementEntity.init(schemaCustomEntity, formDOM, gspMetadata);

        metadataElementDependencyDetail.setSourceElement(MetadataElementGenerator.generate(entityRelyCheckType, sourceElementEntity));
        metadataElementDependencyDetail.setReferenceType(entityRelyCheckType.getReferenceType());
        metadataElementDependencyDetail.setTargetElementLocator(MetadataVOElementLocatorGenerator.generate(entityRelyCheckType, schemaCustomEntity.getId()));

        ListUtility.add(entityDependencyDetailList, metadataElementDependencyDetail);


        if (schemaCustomEntity.getType() != null) {
            // 添加对应的 field 字段依赖信息
            List<MetadataElementDependencyDetail> elementDependencyDetailList = this.schemaFieldDependencyGenerator.generateDependencyDetailWithSchemaFieldList(schemaCustomEntity, schemaCustomEntity.getType().getFields(), formDOM, gspMetadata);
            ListUtility.add(entityDependencyDetailList, elementDependencyDetailList);

            // 如果当前 entity 存在子表  那么递归进行子表依赖项的构造
            if (ListUtility.isNotEmpty(schemaCustomEntity.getType().getEntities())) {
                List<MetadataElementDependencyDetail> childEntityDependencyDetailList = this.generateDependencyDetailWithSchemaEntityList(schemaCustomEntity.getType().getEntities(), formDOM, gspMetadata);
                ListUtility.add(entityDependencyDetailList, childEntityDependencyDetailList);
            }
        }

        return entityDependencyDetailList;
    }
}
